
#include "Tortuga.h"
#include "../FabricasObjetosJuego.h"
#include <iostream>
#include <algorithm>

const int EstadoTortuga::Aplastando = 0;
const int EstadoTortuga::Volteada = 1;
const int EstadoTortuga::Escapando = 2;
const int EstadoTortuga::Muriendo = 3;
const int EstadoTortuga::SinParticular = 4;
const vector<int> EstadoTortuga::acciones = make_vector<int>() << EstadoBasico::Movimiento;
const vector<string> EstadoTortuga::descripcionAcciones = make_vector<string>() << "mover";
const vector<int> EstadoTortuga::accionesParticulares = make_vector<int>() << EstadoTortuga::Aplastando << EstadoTortuga::Volteada << EstadoTortuga::Escapando << EstadoTortuga::Muriendo;
const vector<string> EstadoTortuga::descripcionAccionesParticulares = make_vector<string>() << "aplastar" << "voltear" << "escapar" << "morir";

Tortuga::Tortuga(int x, int y, int maximoX, int maximoY, Orientacion orientacion) : ObjetoMovible(x, y, maximoX, maximoY, orientacion) {

	if (orientacion == Derecha)
		estadoDerecha = Empezo;
	else // if (orientacion == Izquierda)
		estadoIzquierda = Empezo;

	estado = EstadoBasico::Movimiento;
	estadoParticular = EstadoTortuga::SinParticular;
	prioridad = 2;
	tipo = ENEMIGO;
	
	srand( time(NULL) );
}

void Tortuga::Actualizar(Uint32 time) {

	if (estadoDerecha == Moviendo) {
		MoverDerecha(maximoX, time - lastTimeActualizar);
		if (getX() > maximoX) {
			setEstadoParticular(EstadoTortuga::Muriendo);
			setActivo(false);
		}
	}
	
	if (estadoIzquierda == Moviendo) {
		MoverIzquierda(time - lastTimeActualizar);
		if (getX() + ancho < 0){
			setEstadoParticular(EstadoTortuga::Muriendo);
			setActivo(false);
		}
	}
	
	if (estadoDerecha == Empezo) {
		estadoDerecha = Moviendo;
		setEstado(EstadoBasico::Movimiento);
	}
	
	if (estadoIzquierda == Empezo) {
		estadoIzquierda = Moviendo;
		setEstado(EstadoBasico::Movimiento);
	}
}

pair<idImagen_t, int> Tortuga::getDibujable(Uint32 time) {

	pair<idImagen_t, int> dibujable;
	
	if (estadoParticular == EstadoTortuga::SinParticular) {
		if (estado == EstadoBasico::Quieto)
			setEstado(EstadoBasico::Movimiento);
		dibujable = ObjetoMovible::getDibujable(time);
	}
	else {
		bool status;
		dibujable = getDibujableParticular(accionesParticulares.at(estadoParticular), time, &status);
		if (estadoParticular == EstadoTortuga::Aplastando) {
			if (!status) estadoParticular = EstadoTortuga::Volteada;
		}
		else if (estadoParticular == EstadoTortuga::Muriendo) {
			if (!status) {
				estadoVida = Muerto;
				if (rand() % 100 > 50 ) {
					FabricaBonus::CrearObjeto(getX(), getY(), orientacion);
				}
			}
		}
	}
	
    return dibujable;
}

void Tortuga::SepararCaparazon() {
	
	estadoParticular = EstadoTortuga::Aplastando;
	v_acciones = accionesParticulares;
	animacionActual = 0;
	
	estadoDerecha = SinMovimiento;
	estadoIzquierda = SinMovimiento;
}

void Tortuga::EscaparDerecha() {
	
	estadoDerecha = Empezo;
	estadoIzquierda = SinMovimiento;
	estado = EstadoBasico::Movimiento;
	setVelocidad(getVelocidad()*4);
	setEstadoParticular(EstadoTortuga::Escapando);
}

void Tortuga::EscaparIzquierda() {
	
	estadoDerecha = SinMovimiento;
	estadoIzquierda = Empezo;
	estado = EstadoBasico::Movimiento;
	setVelocidad(getVelocidad()*4);
	setEstadoParticular(EstadoTortuga::Escapando);
}

void Tortuga::FrenarEscape() {
	
	estadoDerecha = SinMovimiento;
	estadoIzquierda = SinMovimiento;
	setVelocidad(0);
	Frenar();
}

int Tortuga::indexEstado(int estado) {
	
	vector<int> estados = EstadoTortuga::acciones;
	
	unsigned int posicion = find(estados.begin(), estados.end(), estado) - estados.begin();
	
	if (posicion >= estados.size())
		return -1;
		
	return posicion;
}

void Tortuga::addAccionParticular(int idImagen, int cuadros) {
	Animacion *animacion = new Animacion (cuadros, 0, idImagen, ancho, alto);
    accionesParticulares.push_back(animacion);
}

int Tortuga::getEstadoParticular() {
	return estadoParticular;
}

void Tortuga::setEstadoParticular(int estado) {
	estadoParticular = estado;
}

void Tortuga::Morir() {
	setEstadoParticular(EstadoTortuga::Muriendo);
	setActivo(false);
}

void Tortuga::ColisionarConPersonaje(ObjetoEstatico* personaje, int colX, int colY, int colXvieja, int colYvieja) {

	Personaje* per = dynamic_cast<Personaje*> (personaje);

	per->StartSonido (SonidosPersonaje::Colision);

	if (per->getInvencibilidad()) {
		setEstadoParticular(EstadoTortuga::Muriendo);
		setActivo(false);
		return;
	}
	if (getEstadoParticular() == EstadoTortuga::Aplastando) return;

	if (colY > colX) {
		if (getEstadoParticular() == EstadoTortuga::SinParticular || getEstadoParticular() == EstadoTortuga::Escapando) {
			per->restarVida();
			per->RestarPuntos(PUNTOS_RESTAR);
			CambiarSentido(1,1, true);
			setPosicion(getPosicionAnt().getX(), getPosicionAnt().getY());
		}
		else if (getEstadoParticular() == EstadoTortuga::Volteada) {
			if (per->getOrientacion() == Derecha) {
				setPosicion(per->getX() + per->getAncho() + 15, getY());
				EscaparDerecha();
			}
			else {
				setPosicion(per->getX() - getAncho() - 15, getY());
				EscaparIzquierda();
			}
		}
	}
	else if (colX > colY && (per->getVelocidadY() < 0)) {
		if (getEstadoParticular() == EstadoTortuga::SinParticular) {
			SepararCaparazon();
			Frenar();
			per->setVelocidadY(150);
			per->setPosicion(per->getX(), getY()- per->getAlto());
		}
		else if (getEstadoParticular() == EstadoTortuga::Volteada) {
			Morir();
			per->SumarPuntos(PUNTOS_SUMAR);
			per->setVelocidadY(150);
			per->setPosicion(per->getX(), getY()- per->getAlto());
		}
		else if (getEstadoParticular() == EstadoTortuga::Escapando) {
			FrenarEscape();
			setEstadoParticular(EstadoTortuga::Volteada);
			per->setVelocidadY(150);
			per->setPosicion(per->getX(), getY()- per->getAlto());
		}
	}
	else {
		per->RestarPuntos(PUNTOS_RESTAR);
		per->restarVida();
		CambiarSentido(1,1, true);
		setPosicion(getPosicionAnt().getX(), getPosicionAnt().getY());
	}
}

void Tortuga::ColisionarConEnemigo(ObjetoEstatico* movible, int colX, int colY, int colXvieja, int colYvieja) {

	ObjetoMovible* mov = dynamic_cast<ObjetoMovible*> (movible);

	if (getPrioridad() < mov->getPrioridad()) mov->ColisionarConEnemigo(this, colX, colY, colXvieja, colYvieja);

	if (movible->getEstadoVida() == Muerto) return;

	if (estadoParticular == EstadoTortuga::Escapando) mov->Morir();
	else {
		if (colXvieja != 0) {
			if (mov->getVelocidadY() <= 0) movible->setPosicion(movible->getX(), getY() - movible->getAlto());
			else movible->setPosicion(movible->getX(), getY() + getAlto());
		}
		else if (colYvieja != 0) {
			CambiarSentido(getX(), getY(), true);
			mov->CambiarSentido(getX(), getAncho());
			/**** esto es cabezaaa, despues pensare mejor como hacerlooo, esta jodido ***/
			if (static_cast<Tortuga*>(movible)->getEstadoParticular() == EstadoTortuga::Escapando) Morir();
		}
		else {
			if (colX >= colY) {
				if (mov->getVelocidadY() <= 0) movible->setPosicion(movible->getX(), getY() - movible->getAlto());
				else movible->setPosicion(movible->getX(), getY() + getAlto());
			}
			else {
				CambiarSentido(getX(), getY(), true);
				mov->CambiarSentido(getX(), getAncho());
				/**** esto es cabezaaa, despues pensare mejor como hacerlooo, esta jodido ***/
				if (mov->getPrioridad() == 2) if (static_cast<Tortuga*>(movible)->getEstadoParticular() == EstadoTortuga::Escapando) Morir();
			}
		}
	}
}
